package org.littlesun.management.address;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;

import lombok.AllArgsConstructor;

@AllArgsConstructor
public class CityZoneMatcher {

	private MatchResult parent;
	private Collection<City> cities;

	public CityZoneMatcher(City... cities) {
		this(null, cities);
	}
	
	public CityZoneMatcher(List<City> cities) {
		this(null, cities);
	}

	public CityZoneMatcher(MatchResult parent, City... cities) {
		this(parent, Arrays.asList(cities));
	}

	public MatchResult match(String text) {
		String theText = text;
		MatchResult cityMatch = new CityMatcher(cities).match(theText);
		MatchResult zoneMatch;
		City city = null;
		Zone zone = null;
		if (cityMatch.isSuccess() == true) {
			theText = cityMatch.getTextAfterMatch();
			city = (City) cityMatch.getMatchedObject();
			zoneMatch = new ZoneMatcher(cityMatch, city).match(theText);
			if (zoneMatch.isSuccess() == true) {
				theText = zoneMatch.getTextAfterMatch();
				zone = (Zone) zoneMatch.getMatchedObject();
			}
			else {
				if (!city.isZoneAsBeginOfAddress()) {
					List<String> suggestions = new ArrayList<String>();
					suggestions.addAll(zoneMatch.getSuggestions());
					return new MatchResult(parent, new CityZone(city, null), "", text, suggestions);
				}
				else {
					List<String> suggestions = new ArrayList<String>();
					for(Zone z : city.getZones()) {
						suggestions.add((parent == null ? "" : parent.getFullMatchedOrginalText()) + city.getName() + z.getName());
					}
					return new MatchResult(parent, new CityZone(city, null), "", text, suggestions);
				}
			}
		}
		else {
			zoneMatch = new ZoneMatcher(cityMatch, cities).match(theText);
			if (zoneMatch.isSuccess() == true) {
				theText = zoneMatch.getTextAfterMatch();
			}
			if (zoneMatch.isSuccess() == true) {
				zone = (Zone) zoneMatch.getMatchedObject();
				city = zone.getCity();
			}
			else {
				if (city == null) {
					return new MatchResult(parent, null, "", text, getSuggestions());
				}
			}
		}
		CityZone cityArea = new CityZone(city, zone);
		StringBuffer matchedOrginalText = new StringBuffer();
		if (cityMatch.isSuccess()) {
			matchedOrginalText.append(cityMatch.getMatchedOrginalText());
		}
		if (zoneMatch.isSuccess()) {
			matchedOrginalText.append(zoneMatch.getMatchedOrginalText());
		}
//		String textAfterMatch;
//		if (zoneMatch.isSuccess()) {
//			textAfterMatch = zoneMatch.getMatchedOrginalText();
//		}
//		else {
//			if (cityMatch.isSuccess()) {
//				textAfterMatch = cityMatch.getMatchedOrginalText();
//			}
//			else {
//				throw new RuntimeException();
//			}
//		}
		MatchResult matchResult = new MatchResult(parent, cityArea, matchedOrginalText.toString(), theText);
		return matchResult;
	}	
	
	protected List<String> getSuggestions() {
		String matchedOrginalText = parent == null? "" : parent.getFullMatchedOrginalText();
		List<String> names = new ArrayList<String>();
		for(City city : cities) {
			names.add(matchedOrginalText + city.getName());
		}
		for(City city : cities) {
			if (!city.isZoneAsBeginOfAddress()) {
				for(Zone zone : city.getZones()) {
					names.add(matchedOrginalText + zone.getName());
				}
			}
		}
		return names;
	}

}
